#pragma once

/*
CMyQQHelper helper;
BOOL b = FALSE;
b = helper.Init(L"libqq.dll");
b = helper.libqq_init();
struct qqclient* qq = helper.libqq_create(1234567, "password");
int nLogin = helper.libqq_login(qq);

for( ; qq->process != P_LOGIN; helper.libqq_wait( qq, 1 ))
{
	switch( qq->process )
	{
	case P_LOGGING:
		continue;
	case P_VERIFYING:
		//qqclient_verify( qq, input );
		break;
	case P_DENIED:
		ShellExecute(NULL,"open","http://jihuo.qq.com/",NULL,NULL,SW_SHOWNORMAL);
	case P_ERROR:
	case P_WRONGPASS:
	default:
		int a =1;
		break;
	}
}

WCHAR szName[NICKNAME_LEN] = {0};
helper.libqq_utf8toUC(qq->self->nickname, szName, NICKNAME_LEN);
*/

#define MYQQHELPER_GETPFN(funname) m_funs.m_pfn_##funname

#define MYQQHELPER_CHECKPFN(funname, ERRCODE)	\
	if (NULL==MYQQHELPER_GETPFN(funname)) return ERRCODE

#define MYQQHELPER_GETPROCADDRESS(funname, strfunname)	\
	MYQQHELPER_GETPFN(funname) = (PFN_##funname)GetProcAddress(m_hDll, strfunname)

class CMyQQHelper
{
public:
	CMyQQHelper()
		: m_hDll(NULL)
	{
		ZeroMemory(&m_funs, sizeof(m_funs));
	}

	~CMyQQHelper()
	{
		Uninit();
	}

	BOOL Init(LPCWSTR szDll)
	{
		if (m_hDll)
			return TRUE;

		m_hDll = LoadLibraryW(szDll);
		if (m_hDll)
		{
			MYQQHELPER_GETPROCADDRESS(libqq_init, "libqq_init");
			MYQQHELPER_GETPROCADDRESS(libqq_cleanup, "libqq_cleanup");
			MYQQHELPER_GETPROCADDRESS(libqq_create, "libqq_create");
			MYQQHELPER_GETPROCADDRESS(libqq_login, "libqq_login");
			MYQQHELPER_GETPROCADDRESS(libqq_login_th, "libqq_login_th");
			MYQQHELPER_GETPROCADDRESS(libqq_wait, "libqq_wait");
			MYQQHELPER_GETPROCADDRESS(libqq_logout, "libqq_logout");
			MYQQHELPER_GETPROCADDRESS(libqq_keepalive, "libqq_keepalive");
			MYQQHELPER_GETPROCADDRESS(libqq_detach, "libqq_detach");
			//	int libqq_getmessage( struct qqclient* qq, char* buf, int size, int wait );
			//	int libqq_sendmessage( struct qqclient* qq, uint to, char* buf, char qun_msg );
			MYQQHELPER_GETPROCADDRESS(libqq_updatelist, "libqq_updatelist");
			MYQQHELPER_GETPROCADDRESS(libqq_verify, "libqq_verify");
			MYQQHELPER_GETPROCADDRESS(libqq_remove, "libqq_remove");
			MYQQHELPER_GETPROCADDRESS(libqq_status, "libqq_status");
			MYQQHELPER_GETPROCADDRESS(libqq_refresh, "libqq_refresh");
			//	void libqq_getqunname( struct qqclient* qq, uint ext_id, char* buf );
			//	void libqq_getqunmembername( struct qqclient* qq, uint ext_id, uint uid, char* buf );
			//	void libqq_getbuddyname( struct qqclient* qq, uint uid, char* buf );
			MYQQHELPER_GETPROCADDRESS(libqq_getextrainfo, "libqq_getextrainfo");
			//	void libqq_addbuddy( struct qqclient* qq, uint uid, char* msg );
			MYQQHELPER_GETPROCADDRESS(libqq_delbuddy, "libqq_delbuddy");
			MYQQHELPER_GETPROCADDRESS(libqq_sethttpproxy, "libqq_sethttpproxy");
			MYQQHELPER_GETPROCADDRESS(libqq_utf8toUC, "libqq_utf8toUC");

			return TRUE;
		}
		return FALSE;
	}

	void Uninit()
	{
		if (m_hDll)
		{
			FreeLibrary(m_hDll);
			m_hDll = NULL;
		}
		ZeroMemory(&m_funs, sizeof(m_funs));
	}

public:
	BOOL libqq_init()
	{
		MYQQHELPER_CHECKPFN(libqq_init, FALSE);
		MYQQHELPER_GETPFN(libqq_init)();
		return TRUE;
	}

	BOOL libqq_cleanup()
	{
		MYQQHELPER_CHECKPFN(libqq_cleanup, FALSE);
		MYQQHELPER_GETPFN(libqq_cleanup)();
		return TRUE;
	}

	struct qqclient* libqq_create( UINT nNumber, LPCSTR szPass )
	{
		MYQQHELPER_CHECKPFN(libqq_create, NULL);
		return MYQQHELPER_GETPFN(libqq_create)(nNumber, szPass);
	}

	int libqq_login( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_login, -1);
		return MYQQHELPER_GETPFN(libqq_login)(qq);
	}

	int libqq_login_th( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_login_th, -1);
		return MYQQHELPER_GETPFN(libqq_login_th)(qq);
	}

	int libqq_wait( struct qqclient* qq, int nSec )
	{
		MYQQHELPER_CHECKPFN(libqq_wait, -1);
		return MYQQHELPER_GETPFN(libqq_wait)(qq, nSec);
	}
	
	int libqq_logout( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_logout, -1);
		return MYQQHELPER_GETPFN(libqq_logout)(qq);
	}

	int libqq_keepalive( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_keepalive, -1);
		return MYQQHELPER_GETPFN(libqq_keepalive)(qq);
	}

	int libqq_detach( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_detach, -1);
		return MYQQHELPER_GETPFN(libqq_detach)(qq);
	}

//	int libqq_getmessage( struct qqclient* qq, char* buf, int size, int wait );
//	int libqq_sendmessage( struct qqclient* qq, uint to, char* buf, char qun_msg );
	BOOL libqq_updatelist( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_updatelist, FALSE);
		MYQQHELPER_GETPFN(libqq_updatelist)(qq);
		return TRUE;
	}

	BOOL libqq_verify( struct qqclient* qq, LPCSTR szCode )
	{
		MYQQHELPER_CHECKPFN(libqq_verify, FALSE);
		MYQQHELPER_GETPFN(libqq_verify)(qq, szCode);
		return TRUE;
	}

	BOOL libqq_remove( struct qqclient* qq )
	{
		MYQQHELPER_CHECKPFN(libqq_remove, FALSE);
		MYQQHELPER_GETPFN(libqq_remove)(qq);
		return TRUE;
	}

	BOOL libqq_status( struct qqclient* qq, enum QQSTATUS nStatus, BOOL bHasCamera )
	{
		MYQQHELPER_CHECKPFN(libqq_status, FALSE);
		MYQQHELPER_GETPFN(libqq_status)(qq, nStatus, bHasCamera);
		return TRUE;
	}

	BOOL libqq_refresh( struct qqclient* qq, UINT* pNumber )
	{
		MYQQHELPER_CHECKPFN(libqq_refresh, FALSE);
		*pNumber = MYQQHELPER_GETPFN(libqq_refresh)(qq);
		return TRUE;
	}

//	void libqq_getqunname( struct qqclient* qq, uint ext_id, char* buf );
//	void libqq_getqunmembername( struct qqclient* qq, uint ext_id, uint uid, char* buf );
//	void libqq_getbuddyname( struct qqclient* qq, uint uid, char* buf );
	BOOL libqq_getextrainfo( struct qqclient* qq, UINT uid )
	{
		MYQQHELPER_CHECKPFN(libqq_getextrainfo, FALSE);
		MYQQHELPER_GETPFN(libqq_getextrainfo)(qq, uid);
		return TRUE;
	}

//	void libqq_addbuddy( struct qqclient* qq, uint uid, char* msg );
	BOOL libqq_delbuddy( struct qqclient* qq, UINT uid )
	{
		MYQQHELPER_CHECKPFN(libqq_delbuddy, FALSE);
		MYQQHELPER_GETPFN(libqq_delbuddy)(qq, uid);
		return TRUE;
	}

	BOOL libqq_sethttpproxy( struct qqclient* qq, LPCSTR szIP, USHORT nPort )
	{
		MYQQHELPER_CHECKPFN(libqq_sethttpproxy, FALSE);
		MYQQHELPER_GETPFN(libqq_sethttpproxy)(qq, szIP, nPort);
		return TRUE;
	}

	BOOL libqq_utf8toUC( LPCSTR pSrc, WCHAR* pTar, UINT nLen )
	{
		MYQQHELPER_CHECKPFN(libqq_utf8toUC, FALSE);
		MYQQHELPER_GETPFN(libqq_utf8toUC)(pSrc, pTar, nLen);
		return TRUE;
	}

private:
	typedef void (__stdcall* PFN_libqq_init)();
	typedef void (__stdcall* PFN_libqq_cleanup)();
	
	typedef struct qqclient* (__stdcall* PFN_libqq_create)( UINT nNumber, LPCSTR szPass );
	typedef int (__stdcall* PFN_libqq_login)( struct qqclient* qq );
	typedef int (__stdcall* PFN_libqq_login_th)( struct qqclient* qq );
	typedef int (__stdcall* PFN_libqq_wait)( struct qqclient* qq, int nSec );
	
	typedef int (__stdcall* PFN_libqq_logout)( struct qqclient* qq );
	typedef int (__stdcall* PFN_libqq_keepalive)( struct qqclient* qq );
	typedef int (__stdcall* PFN_libqq_detach)( struct qqclient* qq );
	//	int libqq_getmessage( struct qqclient* qq, char* buf, int size, int wait );
	//	int libqq_sendmessage( struct qqclient* qq, uint to, char* buf, char qun_msg );
	typedef void (__stdcall* PFN_libqq_updatelist)( struct qqclient* qq );
	typedef void (__stdcall* PFN_libqq_verify)( struct qqclient* qq, LPCSTR szCode );
	typedef void (__stdcall* PFN_libqq_remove)( struct qqclient* qq );
	typedef void (__stdcall* PFN_libqq_status)( struct qqclient* qq, enum QQSTATUS nStatus, BOOL bHasCamera );
	typedef UINT (__stdcall* PFN_libqq_refresh)( struct qqclient* qq );
	//	void libqq_getqunname( struct qqclient* qq, uint ext_id, char* buf );
	//	void libqq_getqunmembername( struct qqclient* qq, uint ext_id, uint uid, char* buf );
	//	void libqq_getbuddyname( struct qqclient* qq, uint uid, char* buf );
	typedef void (__stdcall* PFN_libqq_getextrainfo)( struct qqclient* qq, UINT uid );
	//	void libqq_addbuddy( struct qqclient* qq, uint uid, char* msg );
	typedef void (__stdcall* PFN_libqq_delbuddy)( struct qqclient* qq, UINT uid );
	typedef void (__stdcall* PFN_libqq_sethttpproxy)( struct qqclient* qq, LPCSTR szIP, USHORT nPort );
	typedef void (__stdcall* PFN_libqq_utf8toUC)( LPCSTR pSrc, WCHAR* pTar, UINT nLen );

private:
	struct MYQQFUNS
	{
		PFN_libqq_init m_pfn_libqq_init;
		PFN_libqq_cleanup m_pfn_libqq_cleanup;
		PFN_libqq_create m_pfn_libqq_create;
		PFN_libqq_login m_pfn_libqq_login;
		PFN_libqq_login_th m_pfn_libqq_login_th;
		PFN_libqq_wait m_pfn_libqq_wait;
		
		PFN_libqq_logout m_pfn_libqq_logout;
		PFN_libqq_keepalive m_pfn_libqq_keepalive;
		PFN_libqq_detach m_pfn_libqq_detach;
		//	int libqq_getmessage( struct qqclient* qq, char* buf, int size, int wait );
		//	int libqq_sendmessage( struct qqclient* qq, uint to, char* buf, char qun_msg );
		PFN_libqq_updatelist m_pfn_libqq_updatelist;
		PFN_libqq_verify m_pfn_libqq_verify;
		PFN_libqq_remove m_pfn_libqq_remove;
		PFN_libqq_status m_pfn_libqq_status;
		PFN_libqq_refresh m_pfn_libqq_refresh;
		//	void libqq_getqunname( struct qqclient* qq, uint ext_id, char* buf );
		//	void libqq_getqunmembername( struct qqclient* qq, uint ext_id, uint uid, char* buf );
		//	void libqq_getbuddyname( struct qqclient* qq, uint uid, char* buf );
		PFN_libqq_getextrainfo m_pfn_libqq_getextrainfo;
		//	void libqq_addbuddy( struct qqclient* qq, uint uid, char* msg );
		PFN_libqq_delbuddy m_pfn_libqq_delbuddy;
		PFN_libqq_sethttpproxy m_pfn_libqq_sethttpproxy;
		PFN_libqq_utf8toUC m_pfn_libqq_utf8toUC;
	};

	HMODULE m_hDll;
	MYQQFUNS m_funs;
};
